<?php

declare(strict_types=1);

namespace RX\Helpers;

use EasySwoole\Utility\SnowFlake;

class RandomHelper
{
    /**
     * 生产随机数
     * @param int $length 长度
     * @param string $alphabet 元素集合
     * @return false|string
     */
    public static function character(
        int $length = 6,
        string $alphabet = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
    ): string
    {
        mt_srand();
        if ($length >= strlen($alphabet)) {
            $rate     = intval($length / strlen($alphabet)) + 1;
            $alphabet = str_repeat($alphabet, $rate);
        }
        return substr(str_shuffle($alphabet), 0, $length);
    }


    /**
     * 生产指定长度的随机数字
     * @param int $length 长度
     * @return false|string
     */
    public static function number(int $length = 6): string
    {
        return static::character($length, '0123456789');
    }


    /**
     * 数组中随机返回一个
     * @param array $data 数据
     * @return mixed|null
     */
    public static function arrayRandOne(array $data)
    {
        if (empty($data)) {
            return null;
        }
        mt_srand();
        return $data[array_rand($data)];
    }

    /**
     * 生产一个UUID4
     * 有概率重复|短时间内可以认为唯一
     * @return string
     */
    public static function makeUUIDV4(): string
    {
        mt_srand();
        $charId = strtolower(md5(uniqid((string)mt_rand(), true)));
        $hyphen = '-';
        return substr($charId, 0, 8) . $hyphen .
               substr($charId, 8, 4) . $hyphen .
               substr($charId, 12, 4) . $hyphen .
               substr($charId, 16, 4) . $hyphen .
               substr($charId, 20, 12);
    }


    public static function makeSnowFlake(string $prefix = "", $dataCenterId = 0, $workerId = 0): string
    {
        return $prefix . SnowFlake::make($dataCenterId, $workerId);
    }

    public static function makeUniqueOrderNo()
    {
        return date("ymdHis") . substr(self::makeSnowFlake(), 10) . rand(100000, 999999);
    }

    public static function makeMillisecond()
    {
        list($t1, $t2) = explode(' ', microtime());
        return (string)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
    }

    public static function makeUID(int $num = 18, string $suffix = "")
    {
        if ($num <= 14) {
            return hrtime(true);
        }
        $randNum = $num - 13;
        $rand    = rand(1, (int)str_repeat('9', $randNum));
        $randStr = str_pad((string)$rand, $randNum, '0', STR_PAD_LEFT);
        return hrtime(true) . $randStr . $suffix;
    }
}
